package scalab.core

//not final to allow wrapping...
//extends java.io.File
// => override def getPath = getCanonicalPath...
import java.io.File
@serializable
abstract class Resource(p: String) extends File(p){

	private def this() = this(".")
	val canonicalPath: String = getCanonicalPath

  //TODO:def apply(path: String*)

/*  val file: File = (new File(p)).getCanonicalFile()
	val path: String = file.getPath()
*/
	override def toString: String = p

	override def equals(that: Any): Boolean = 
		that.isInstanceOf[Resource] && compare(that.asInstanceOf[Resource]) == 0

	/**
	* reversed string comparison. Because pathes in builds often begin with a 
	*	common directory => this is more efficient to compare from the end.
	*/
	def compare(that: Resource): Int = 
		scalab.utils.Path.compareDesc(this.canonicalPath, that.canonicalPath)
}

object Resource{

	import scala.collection.mutable.HashMap
	import scalab.utils.Pathname

	//optimization:
	//look for path => map ascending order, path descending...
	//insert new path => reverse path and insert...
	//=> avoids common path collisions
	private[core] lazy val allResources: HashMap[Pathname, Resource] = new HashMap[Pathname, Resource]
	def apply(p: String): Resource = {
		val r: Resource = new Resource(p){}
		val pathname = Pathname(r.canonicalPath)
		allResources.get(pathname) match{
			case Some(res) => res
			case None => 
				allResources.update(pathname, r)
				r
		}
	}

	def apply(paths: Iterable[String]): Iterable[Resource] = paths map {p => apply(p)}
	def apply(paths: String*): Iterable[Resource] = apply(paths)

	def canonicalPath(path: String): String = apply(path).canonicalPath

	def resource2ordered(r: Resource): Ordered[Resource] = new Ordered[Resource]{
		def compare(that: Resource): Int =
			scalab.utils.Path.compareDesc(r.canonicalPath, that.canonicalPath)
	}

	def orderResources(res: Iterable[Resource]) = {
		import scala.collection.immutable.TreeSet
		(new TreeSet[Resource]()(resource2ordered _)) ++ res
	}
}
